package com.ys.service.purchase.impl;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ys.dto.AddDto;
import com.ys.entity.flow.YspModel;
import com.ys.entity.purchase.TcgInvoiceOffset;
import com.ys.entity.purchase.TcgInvoiceRegist;
import com.ys.entity.purchase.TcgInvoiceRegistItem;
import com.ys.entity.sys.TsUserChange;
import com.ys.entity.sys.YsMenu;
import com.ys.entity.sys.YsProcInst;
import com.ys.enume.flow.FlowEnum;
import com.ys.enume.flow.YsProcInstEnum;
import com.ys.mapper.purchase.PurchaseMapper;
import com.ys.mapper.purchase.TcgInvoiceRegistItemMapper;
import com.ys.mapper.purchase.TcgInvoiceRegistMapper;
import com.ys.service.flow.YspTaskService;
import com.ys.service.purchase.TcgInvoiceRegistService;
import com.ys.util.shiro.ShiroUtils;
import com.ys.vo.Flow;
import com.ys.vo.R;

@Service("tcgInvoiceRegistService")
public class TcgInvoiceRegistServiceImpl implements TcgInvoiceRegistService {

	@Autowired
	private PurchaseMapper purchaseMapper;
	@Autowired
	private TcgInvoiceRegistMapper tcgInvoiceRegistMapper;
	@Autowired
	private TcgInvoiceRegistItemMapper tcgInvoiceRegistItemMapper;
	
	@Autowired
	private YspTaskService yspTaskService;
	
	@Override
	@Transactional
	public R add(String bid, String bidInvoiceOffset, String remark, String invoiceNo, String invoiceDay,
			BigDecimal taxPercent, BigDecimal amountNoTax, BigDecimal tax, BigDecimal amountWithTax,
			String detailArr, Long menuId) throws Exception {
		
		if (tax == null) {
			return R.error("统一税点不能为空");
		} else if (taxPercent.compareTo(BigDecimal.ZERO) < 0 || taxPercent.compareTo(BigDecimal.ONE) > 0) {
			return R.error("统一税点取值在0~1之间");
		}
		
		// 验证订单号
		if (new TcgInvoiceRegist().setBid(bid).count() > 0) {
			return R.error("该订单号已存在");
		}
		
		// 验证预核销单号
		if (bidInvoiceOffset == null) {
			return R.error("核销单号不能为空");
		}
		TcgInvoiceOffset tcgInvoiceOffset = new TcgInvoiceOffset().setBid(bidInvoiceOffset).queryFirst();
		if (tcgInvoiceOffset == null) {
			return R.error("预核销单不存在");
		}
		
		// 验证详情数据不能为空
		JSONArray detailJA = JSON.parseArray(detailArr);
		if (detailJA == null || detailJA.size() == 0) {
			return R.error("详情数据不能为空");
		}
		
		String loginUserId = ShiroUtils.getUserId();
		
		TsUserChange tsUserChange = new TsUserChange().setUserId(loginUserId).setStatus(1).queryFirst();
		
		// 添加发票登记单
		TcgInvoiceRegist entity = null;
		{
			Integer effectStock = FlowEnum.EffectStock.NOT_EFFECT.value;
			Long createChangeId = tsUserChange.getId();
			Long invoiceOffsetId= tcgInvoiceOffset.getId();
			String annexFile = null;
			entity = TcgInvoiceRegist.tcgInvoiceRegist(bid, effectStock, createChangeId, invoiceOffsetId, annexFile, invoiceNo, invoiceDay, taxPercent, amountNoTax, tax, amountWithTax, remark, 1);
		}
		tcgInvoiceRegistMapper.insert(entity);
		
		// 添加发票登记单明细
		for (int i = 0; i < detailJA.size(); i++) {
			JSONObject detailJO = detailJA.getJSONObject(i);
			
			String pbid = bid;
			Long invoiceOffsetItemId = detailJO.getLong("invoiceOffsetItemId");
			BigDecimal subSinglePriceNoTax = detailJO.getBigDecimal("subPurchasePriceNoTax");
			BigDecimal subTotalPriceNoTax = detailJO.getBigDecimal("offsetAmountNoTax");
			TcgInvoiceRegistItem tcgInvoiceRegistItem = TcgInvoiceRegistItem.tcgInvoiceRegistItem(pbid, invoiceOffsetItemId, subSinglePriceNoTax, subTotalPriceNoTax, 1);
			tcgInvoiceRegistItemMapper.insert(tcgInvoiceRegistItem);
		}
		
		/*
		 * 流程初始化
		 */
		YsMenu ysMenu = new YsMenu().setId(menuId).queryFirst();
		if (ysMenu.getFlowModelId().longValue() != 0L) {
			YspModel yspModel = new YspModel().setId(ysMenu.getFlowModelId()).queryFirst();
			String codeModel = yspModel.getCode();
			String createUserId = ShiroUtils.getUserId();
			yspTaskService.init(codeModel, bid, createUserId);
		}
		
		return R.ok(AddDto.gotoEdit("/web/purchase/tcgInvoiceRegist/toFlow?bid=" + entity.getBid()));
	}
	
	@Override
	@Transactional
	public R edit(String bid, String bidInvoiceOffset, String remark, String invoiceNo, String invoiceDay,
			BigDecimal taxPercent, BigDecimal amountNoTax, BigDecimal tax, BigDecimal amountWithTax,
			String detailArr, Long menuId) throws Exception {
		
		if (tax == null) {
			return R.error("统一税点不能为空");
		} else if (taxPercent.compareTo(BigDecimal.ZERO) < 0 || taxPercent.compareTo(BigDecimal.ONE) > 0) {
			return R.error("统一税点取值在0~1之间");
		}
		
		// 验证预核销单号
		if (bidInvoiceOffset == null) {
			return R.error("核销单号不能为空");
		}
		TcgInvoiceOffset tcgInvoiceOffset = new TcgInvoiceOffset().setBid(bidInvoiceOffset).queryFirst();
		if (tcgInvoiceOffset == null) {
			return R.error("预核销单不存在");
		}
		
		Integer stateFlow = yspTaskService.flowState(bid);
		if (stateFlow != YsProcInstEnum.StateFlow.INIT.value) {
			return R.error("非制单中数据，无法修改");
		}
		
		// 验证是否制单人
		YsProcInst ysProcInst = new YsProcInst().setBid(bid).queryFirst();
		if (!ysProcInst.getCreateUserId().equals(ShiroUtils.getUserId())) {
			return R.error("非制单人无法修改");
		}
		
		// 验证详情数据不能为空
		JSONArray detailJA = JSON.parseArray(detailArr);
		if (detailJA == null || detailJA.size() == 0) {
			return R.error("详情数据不能为空");
		}
		
		TcgInvoiceRegist entity = new TcgInvoiceRegist().setBid(bid).queryFirst();
		// 更新发票登记单主表数据
		entity
			.setInvoiceOffsetId(tcgInvoiceOffset.getId())
			.setRemark(remark)
			.setInvoiceNo(invoiceNo)
			.setInvoiceDay(invoiceDay)
			.setTaxPercent(taxPercent)
			.setAmountNoTax(amountNoTax)
			.setTax(tax)
			.setAmountWithTax(amountWithTax);
		tcgInvoiceRegistMapper.update(entity);
		
		
		// 删除旧的发票登记单明细
		purchaseMapper.deleteBatchTcgInvoiceRegistByBid(bid);
		
		// 添加发票登记单明细
		for (int i = 0; i < detailJA.size(); i++) {
			JSONObject detailJO = detailJA.getJSONObject(i);
			
			String pbid = bid;
			Long invoiceOffsetItemId = detailJO.getLong("invoiceOffsetItemId");
			BigDecimal subSinglePriceNoTax = detailJO.getBigDecimal("subPurchasePriceNoTax");
			BigDecimal subTotalPriceNoTax = detailJO.getBigDecimal("offsetAmountNoTax");
			TcgInvoiceRegistItem tcgInvoiceRegistItem = TcgInvoiceRegistItem.tcgInvoiceRegistItem(pbid, invoiceOffsetItemId, subSinglePriceNoTax, subTotalPriceNoTax, 1);
			tcgInvoiceRegistItemMapper.insert(tcgInvoiceRegistItem);
		}
		
		return R.ok(AddDto.gotoEdit("/web/purchase/tcgInvoiceRegist/toFlow?bid=" + bid));
	}

	@Override
	@Transactional
	public R flowPass(String bid, String loginUserId) throws Exception {
		
		// 若流程是初始化状态，需验证子表核销总额 = 母表含税金额
		YsProcInst ysProcInst = new YsProcInst().setBid(bid).queryFirst();
		TcgInvoiceRegist tcgInvoiceRegist = null;
		if (ysProcInst.getStateFlow() == YsProcInstEnum.StateFlow.INIT.value) {
			tcgInvoiceRegist = new TcgInvoiceRegist().setBid(bid).queryFirst();
			
			TcgInvoiceOffset tcgInvoiceOffset = new TcgInvoiceOffset().setId(tcgInvoiceRegist.getInvoiceOffsetId()).queryFirst();
			
			if (tcgInvoiceRegist.getAmountWithTax().compareTo(tcgInvoiceOffset.getOffsetTotalAmount()) != 0) {
				return R.error("核销总额与含税金额不一致");
			}
		}
		
		try {
			Flow f = yspTaskService.flowPass(bid, loginUserId);
			if (f.getCode() == Flow.Code.FAILED.value) {
				return R.error(f.getMsg());
			} else if (f.getState() == Flow.State.FINISH.value) {
				flowFinish(bid);
			}
			return R.ok();
		} catch (Exception e) {
			e.printStackTrace();
			return R.error("服务器正在开小差，请联系客服");
		}
	}

	@Override
	public R flowRefuse(String bid, String reason, String loginUserId) throws Exception {
		
		R r = yspTaskService.flowRefuse(bid, reason, loginUserId);
		return r;
	}

	@Override
	@Transactional
	public void flowFinish(String bid) throws Exception {

		TcgInvoiceRegist entity = new TcgInvoiceRegist().setBid(bid).queryFirst();
		
		YsProcInst ysProcInst = new YsProcInst().setBid(entity.getBid()).queryFirst();
		if (ysProcInst.getStateFlow() != YsProcInstEnum.StateFlow.FINISH.value) {
			return;
		}
		
		entity.setEffectStock(FlowEnum.EffectStock.EFFECTED.value);
		tcgInvoiceRegistMapper.update(entity);
		
	}

	@Override
	@Transactional
	public R deleteTrue(Long id) throws Exception {
		if (id == null) {
			return R.error("ID不能为空");
		}
		TcgInvoiceRegist entity = new TcgInvoiceRegist().setId(id).queryFirst();
		if (entity.getEffectStock() == FlowEnum.EffectStock.EFFECTED.value) {
			return R.error("已生效数据无法删除");
		}
		// 验证是否制单人
		String loginUserId = ShiroUtils.getUserId();
		TsUserChange tsUserChange = new TsUserChange().setId(entity.getCreateChangeId()).queryFirst();
		
		if (!tsUserChange.getUserId().equals(loginUserId)) {
			return R.error("非制单人，无法删除");
		}
		
		// 删除主数据
		tcgInvoiceRegistMapper.deleteTrue(id);
		
		// 删除子数据
		List<TcgInvoiceRegistItem> listDetail = new TcgInvoiceRegistItem().setPbid(entity.getBid()).queryList();
		for(TcgInvoiceRegistItem detail : listDetail) {
			tcgInvoiceRegistItemMapper.deleteTrue(detail.getId());
		}
		
		yspTaskService.flowDelete(entity.getBid(), loginUserId);
		return R.ok();
	}



	//获取列表数据
	@Override
	@Transactional
	public Map<String,Object> getExtraParam(String bid) throws Exception{
		Map<String, Object> extraParam = new TcgInvoiceRegist()

				.setBid(bid)
				.addLeftJoin("TCG_InvoiceOffset AA ON AA.Id = A.InvoiceOffsetId")
				.addField("AA.Bid bidInvoiceOffset")
				.addField("AA.OffsetTotalAmount offsetTotalAmount")

				.addLeftJoin("TB_CompanyInfo BB ON BB.Vid = AA.CompanyVid")
				.addField("BB.Vname companyVname")
				.addField("BB.Tax companyTax")

				.addLeftJoin("TCW_PartnerBankInfo CC ON CC.Id = AA.PartnerBankInfoId")
				.addField("CC.PartnerName partnerName")
				.addField("CC.Vgssh partnerVgssh")

				.addLeftJoin("YS_ProcInst D on D.Bid = A.Bid")
				.addField("CONVERT(VARCHAR(20), D.UpdateTime, 120) auditTime")
				.queryFirstMap();
		return extraParam;
	}
	//获取子列表数据
	@Override
	@Transactional
	public List<Map<String, Object>> getItemList( String bid) throws Exception{
		List<Map<String, Object>> sonlist = new TcgInvoiceRegistItem()
				.setPbid(bid)

				.addLeftJoin("TCG_InvoiceRegist AAA ON AAA.Bid = A.Pbid")

				.addLeftJoin("TCG_InvoiceOffsetItem B ON B.Id = A.InvoiceOffsetItemId")
				.addField("B.InvoiceModelNo invoiceModelNo")
				.addField("B.InvoiceName invoiceName")
				.addField("B.OffsetNum offsetNum")
				.addField("B.OffsetAmount offsetAmount")
				.addField("ROUND(B.OffsetAmount / (1 + AAA.TaxPercent), 2) offsetAmountNoTax")
				.addField("(B.OffsetAmount - ROUND(B.OffsetAmount / (1 + AAA.TaxPercent), 2)) subTax")

				.addLeftJoin("TCG_PurchaseContractItem AA ON AA.Id = B.PurchaseContractItemId")
				.addField("AA.SubPurchasePrice subPurchasePrice")

				.addField("ROUND(AA.SubPurchasePrice / (1 + AAA.TaxPercent), 2) subPurchasePriceNoTax")

				.addLeftJoin("TCG_PurchaseContract BB ON BB.Bid = AA.Pbid")
				.addField("BB.Bid bidPurchaseContract")

				.addLeftJoin("TCG_PurchaseAppointOrderProductComponent CC ON CC.Id = AA.OrderProductComponentId")
				.addField("CC.SubCode subCode")
				.addField("CC.SubName subName")
				.addField("CC.SubCodeMerge subCodeMerge")
				.addLeftJoin("TCG_PurchaseAppointOrderItem DD ON DD.Id = CC.Pid")
				.addField("DD.Pbid bidPurchaseAppointOrder")
				.addField("DD.ProductCode productCode")
				.addField("DD.ProductName productName")
				.addField("DD.CodeMerge codeMerge")
				.addLeftJoin("TCG_PurchaseAppointOrder EE ON EE.Bid = DD.Pbid")
				.addField("EE.Vgsbm vgsbm")
				.addLeftJoin("THR_OperateCompanyApply FF ON FF.Vgsbm = EE.Vgsbm")
				.addField("FF.Vgsjc vgsjc")

				.queryMap();

		return sonlist;
	}

}
